// $Id: adopt_depend_clone_release_1.cpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#include <cstring>
#include <boost/test/unit_test.hpp>
#include <xpcom/string.hpp>
#include <xpcom/memory.hpp>

using namespace xpcom;

BOOST_AUTO_TEST_CASE(test_clear_1)
{
    const char* str1 = "I am cute";

    string s1(str1);
    try {
        s1.clear();
        BOOST_CHECK(s1.empty());
        BOOST_CHECK(s1.data() != 0);
        BOOST_CHECK(std::strcmp(s1.data(), "") == 0);
    } catch (std::exception) {
        BOOST_CHECK(false);
    }
}

BOOST_AUTO_TEST_CASE(test_adopt_1)
{
    const char* str1 = "I am cute";
    char* str2;

    string se(string::adopt(0));
    BOOST_CHECK(se.empty());

    str2 = memory::clone(str1, 10);
    string s1(string::adopt(str2));
    BOOST_CHECK(s1 == str2);
    BOOST_CHECK_EQUAL(s1.data(), str2);

    str2 = memory::clone(str1, 10);
    string s2(string::adopt(str2, 4));
    BOOST_CHECK(s2 == "I am");
    BOOST_CHECK_EQUAL(s2.data(), str2);

    str2 = memory::alloc<char>(10);
    std::strcpy(str2, str1);
    string s3(string::adopt(str2, 0));
    BOOST_CHECK(s3 == "");
    BOOST_CHECK(s3.size() == 0);
    BOOST_CHECK_EQUAL(s3.data(), str2);

    str2 = memory::clone(str1 + 3, 7);
    s1.assign(string::adopt(str2, 5));
    BOOST_CHECK(s1 == "m cut");
    BOOST_CHECK_EQUAL(s1.data(), str2);

    str2 = memory::alloc<char>(10);
    std::strcpy(str2, str1);
    string s4 = "aaa";
    s4.assign(string::adopt(str2));
    BOOST_CHECK(s4 == str2);
    BOOST_CHECK_EQUAL(s4.data(), str2);

    s4.assign(string::adopt(0));
    BOOST_CHECK(s4 == "");
}

BOOST_AUTO_TEST_CASE(test_depend_1)
{
    const char* str1 = "I am cute";
    const char* str2 = "I am so cute";

    string se(string::depend(0));
    BOOST_CHECK(se.empty());

    string s1(string::depend(str1));
    BOOST_CHECK(s1 == str1);
    BOOST_CHECK_EQUAL(s1.data(), str1);

    string s2(string::depend(str1 + 1, 4));
    BOOST_CHECK(s2 == " am ");
    BOOST_CHECK_EQUAL(s2.data(), str1 + 1);

    string s3(string::depend(str1, 0));
    BOOST_CHECK(s3 == "");
    BOOST_CHECK(s3.size() == 0);

    s1.assign(string::depend(str2 + 3, 5));
    BOOST_CHECK(s1 == "m so ");
    BOOST_CHECK_EQUAL(s1.data(), str2 + 3);

    string s4 = "aaa";
    s4.assign(string::depend(str1));
    BOOST_CHECK(s4 == str1);
    BOOST_CHECK_EQUAL(s4.data(), str1);
}

BOOST_AUTO_TEST_CASE(test_literal_1)
{
    string se(string::literal(""));
    BOOST_CHECK(se.empty());

    string s1(string::literal("I am cute"));
    BOOST_CHECK(s1 == "I am cute");
    //BOOST_CHECK_EQUAL(s1.data(), "I am cute");

    string s2 = "aaa";
    s2.assign(string::literal("I am cute"));
    BOOST_CHECK(s2 == s1);
    //BOOST_CHECK_EQUAL(s2.data(), s1.data());
}

BOOST_AUTO_TEST_CASE(test_clone_1)
{
    const char* str1 = "I am cute";
    char* p = 0;

    string s1(str1);
    try {
        p = s1.clone_data();
        BOOST_CHECK(std::strcmp(p, str1) == 0);
    } catch (std::exception) {
        BOOST_CHECK(true);
    }
    memory::free(p);

    string s2;
    try {
        p = s2.clone_data();
        BOOST_CHECK(p == 0);
    } catch (std::exception) {
        BOOST_CHECK(false);
    }
    memory::free(p);
}

BOOST_AUTO_TEST_CASE(test_release_1)
{
    const char* str1 = "I am cute";
    char* p = 0;
    string::size_type n = 0;

    string s1(str1);
    try {
        p = s1.release_data(&n);
        BOOST_CHECK(std::strcmp(p, str1) == 0);
        BOOST_CHECK(n == 9);
        BOOST_CHECK(s1.empty());
        BOOST_CHECK(std::strcmp(s1.c_str(), "") == 0);
    } catch (std::exception) {
        BOOST_CHECK(true);
    }
    memory::free(p);

    string s2;
    try {
        p = s2.release_data(&n);
        BOOST_CHECK(p == 0);
        BOOST_CHECK(n == 0);
        BOOST_CHECK(s2.empty());
    } catch (std::exception) {
        BOOST_CHECK(false);
    }
    memory::free(p);

    string s3(str1);
    try {
        p = s3.release_data();
        BOOST_CHECK(std::strcmp(p, str1) == 0);
        BOOST_CHECK(s3.empty());
        BOOST_CHECK(std::strcmp(s3.c_str(), "") == 0);
    } catch (std::exception) {
        BOOST_CHECK(true);
    }
    memory::free(p);
}
